﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
using System.Net;
using System.IO;

namespace AirlineServer
{
    class JetStarSearch
    {
        public static List<Flight> SearchFlight(string html)
        {
            return GetFlightData(html,false);
        }

        public static List<Flight> SearchReturnFlight(string html)
        {
            return GetFlightData(html, true);
        }

        /*
        private static List<JetStartFlightModel> GetFlightData(string html,bool isReturn)
        {
            List<JetStartFlightModel> result = new List<JetStartFlightModel>();
            HtmlDocument document = new HtmlDocument();
            document.LoadHtml(html);
            HtmlNode root = document.DocumentNode;

            //get flight
            HtmlNodeCollection fly = root.SelectNodes("//table[@class='domestic']");
            if (isReturn == true && fly.Count < 2)
                return null;

            HtmlNodeCollection flights = fly[isReturn?1:0].SelectNodes(".//tbody/tr");//=>depart flight
            for (int i = 0; i < flights.Count - 2; i++) //2 cai cuoi khong co thong tin chuyen bay
            {
                JetStartFlightModel model = new JetStartFlightModel();
                HtmlNode f = flights[i];
                HtmlNodeCollection infoNode = f.SelectNodes(".//td");
                //depart
                HtmlNode departCityNode = infoNode[0].SelectSingleNode(".//a[@class='airport']");
                model._DepartCity = Normalize(departCityNode.InnerText);
                string time = Normalize(infoNode[0].SelectSingleNode(".//strong").InnerText);
                if (time.IndexOf('(') != -1)
                {
                    int index = time.IndexOf('(');
                    model._DepBonusInfo = time.Substring(index, time.IndexOf(')') - index + 1);
                    time = time.Remove(index, time.IndexOf(')') - index + 1).Trim();
                }
                model._DepartTime = DateTime.Parse(time);
                //arrive
                HtmlNode arriveCityNode = infoNode[1].SelectSingleNode(".//a[@class='airport']");
                model._ArriveCity = Normalize(arriveCityNode.InnerText);
                string arr_time = Normalize(infoNode[1].SelectSingleNode(".//strong").InnerText);
                if (arr_time.IndexOf('(') != -1)
                {
                    int arr_index = arr_time.IndexOf('(');
                    model._ArrBonusInfo = arr_time.Substring(arr_index, arr_time.IndexOf(')') - arr_index + 1);
                    arr_time = arr_time.Remove(arr_index, arr_time.IndexOf(')') - arr_index + 1).Trim();
                }
                model._ArriveTime = DateTime.Parse(arr_time);

                //stop
                HtmlNode stop = infoNode[2].SelectSingleNode(".//span[@class='stops']");
                model._Stops = Normalize(stop.InnerText);
                HtmlNode timeToFly = infoNode[2].SelectSingleNode(".//a[@class='duration tooltip-info trigger-flight-detail']");
                model._Time = Normalize(timeToFly.InnerText);
                HtmlNode temp = infoNode[2].SelectSingleNode(".//dd[@class='details flight-summary-details']//p[@class='flight-no-carrier']");
                model._FlightCode = Normalize(temp.SelectSingleNode(".//span").InnerText);
                HtmlNode type = infoNode[2].SelectSingleNode(".//div[@class='legend']//dd");
                model._AirCraftType = Normalize(type.InnerText);


                //get it's market
                HtmlNode mar = infoNode[3].SelectSingleNode(".//div[@class='field']/input");
                if (mar == null)
                {
                    model._Status = "Not Available";
                }
                else
                {
                    model._Market = mar.Attributes["value"].Value;

                    //price
                    HtmlNode price = infoNode[3].SelectSingleNode(".//div[@class='field']/label");
                    if (price != null)
                    {
                        model._TicketPrice = Normalize(price.InnerText);
                    }
                    else
                    {
                        model._TicketPrice = Normalize(infoNode[3].InnerText);
                    }
                }

                result.Add(model);
            }

            return result;
        }
        */

        private static List<Flight> GetFlightData(string html, bool isReturn)
        {
            List<Flight> result = new List<Flight>();
            HtmlDocument document = new HtmlDocument();
            document.LoadHtml(html);
            HtmlNode root = document.DocumentNode;

            //get flight
            HtmlNodeCollection fly = root.SelectNodes("//table[@class='domestic']");
            if (isReturn == true && fly.Count < 2)
                return null;

            HtmlNodeCollection flights = fly[isReturn ? 1 : 0].SelectNodes(".//tbody/tr");//=>depart flight
            for (int i = 0; i < flights.Count - 2; i++) //2 cai cuoi khong co thong tin chuyen bay
            {
                Flight model = new Flight();
                model.Tickets = new List<TicketType>();
                model.AirlineID = 1; //Jetstar
                HtmlNode f = flights[i];
                HtmlNodeCollection infoNode = f.SelectNodes(".//td");
                //depart
                HtmlNode departCityNode = infoNode[0].SelectSingleNode(".//a[@class='airport']");
                model.DepartCity = Normalize(departCityNode.InnerText);
                model.DepartDescription = model.DepartCity;

                string time = Normalize(infoNode[0].SelectSingleNode(".//strong").InnerText);
                if (time.IndexOf('(') != -1)
                {
                    int index = time.IndexOf('(');
                    //model._DepBonusInfo = time.Substring(index, time.IndexOf(')') - index + 1);
                    time = time.Remove(index, time.IndexOf(')') - index + 1).Trim();
                }
                model.DepartTime = DateTime.Parse(time);
                //arrive
                HtmlNode arriveCityNode = infoNode[1].SelectSingleNode(".//a[@class='airport']");
                model.ArriveCity = Normalize(arriveCityNode.InnerText);
                model.ArriveDescription = model.ArriveCity;

                string arr_time = Normalize(infoNode[1].SelectSingleNode(".//strong").InnerText);
                if (arr_time.IndexOf('(') != -1)
                {
                    int arr_index = arr_time.IndexOf('(');
                    //model._ArrBonusInfo = arr_time.Substring(arr_index, arr_time.IndexOf(')') - arr_index + 1);
                    arr_time = arr_time.Remove(arr_index, arr_time.IndexOf(')') - arr_index + 1).Trim();
                }
                model.ArriveTime = DateTime.Parse(arr_time);

                //stop
                HtmlNode stop = infoNode[2].SelectSingleNode(".//span[@class='stops']");
                //model._Stops = Normalize(stop.InnerText);
                HtmlNode timeToFly = infoNode[2].SelectSingleNode(".//a[@class='duration tooltip-info trigger-flight-detail']");
                model.FlightTime = Normalize(timeToFly.InnerText);
                /*
                HtmlNode temp = infoNode[2].SelectSingleNode(".//dd[@class='details flight-summary-details']//p[@class='flight-no-carrier']");
                model._FlightCode = Normalize(temp.SelectSingleNode(".//span").InnerText);
                HtmlNode type = infoNode[2].SelectSingleNode(".//div[@class='legend']//dd");
                model._AirCraftType = Normalize(type.InnerText);
                 */


                //get it's market
                HtmlNode mar = infoNode[3].SelectSingleNode(".//div[@class='field']/input");
                if (mar == null)
                {
                    //model._Status = "Not Available";
                    continue;
                }
                else
                {
                    TicketType ticket = new TicketType();
                    ticket._Name = "Economy cabin";

                    ticket._Value = mar.Attributes["value"].Value;
                    ticket._Basefare = ConvertToLong(mar.Attributes["data-price"].Value);
                    ticket._AXperAdult = ConvertToLong(mar.Attributes["data-fees-adt"].Value);
                    ticket._UEperAdult = ConvertToLong(mar.Attributes["fee-amount-adt1"].Value);


                    //price
                    /*
                    HtmlNode price = infoNode[3].SelectSingleNode(".//div[@class='field']/label");
                    if (price != null)
                    {
                     */
                        ticket._PriceTotal = ticket._Basefare + ticket._AXperAdult;
                        model.Tickets.Add(ticket);

                        result.Add(model);

                }
            }

            return result;
        }

        private static string Normalize(string value)
        {
            value = value.Replace("\n", "");
            value = value.Replace("\t", "");
            value = value.Replace("\r", "");
            value = value.Trim();
            return value;
        }

        private static long ConvertToLong(string value)
        {
            int index = value.IndexOf(',');
            if(index != -1)
                value = value.Substring(0, index);
            if (value.IndexOf('.') != -1)
            {
                value = value.Replace(".","");
            }
            return long.Parse(value);
        }

        public static string GetResponseStream(Info info)
        {
            bool flag = (info._FlightStructure == "RoundTrip");
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://booknow.jetstar.com/Search.aspx?culture=vi-VN");

            request.Method = "POST";

            string d = "__EVENTTARGET=" +
"&__EVENTARGUMENT=" +
"&__VIEWSTATE=/wEPDwUBMGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFJ01lbWJlckxvZ2luU2VhcmNoVmlldyRtZW1iZXJfUmVtZW1iZXJtZTxtWS/I2BXFBfalk96y3LBuGXXD" +
"&pageToken=" +
"&total_price=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$RadioButtonMarketStructure=" + info._FlightStructure +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin1=" + info._DepartCity +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination1=" + info._ArriveCity +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate1=" + info._DepartDay+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate1=" + info._ArriveDay+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListCurrency=" + info._Currency +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin2=" + (flag?info._ArriveCity:"")+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination2=" +(flag?info._DepartCity:"")+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate2=" +(flag?info._ArriveDay:DateTime.Now.AddDays(7).ToShortDateString())+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate2=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin3=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination3=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate3=" + DateTime.Now.AddDays(14).ToShortDateString()+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate3=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin4=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination4=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate4=" + DateTime.Now.AddDays(21).ToShortDateString() +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate4=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin5=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination5=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate5=" + DateTime.Now.AddDays(28).ToShortDateString()+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate5=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketOrigin6=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMarketDestination6=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureDate6=" + DateTime.Now.AddDays(35).ToShortDateString() +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDestinationDate6=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_ADT=" + info._ADT +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_CHD=" + info._CHD +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListPassengerType_INFANT=" + info._INFANT +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$RadioButtonSearchBy=SearchStandard" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMultiCityOrigin1=Origin" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMultiCityDestination1=Destination" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureMultiDate1=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMultiCityOrigin2=Origin" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextBoxMultiCityDestination2=Destination" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$TextboxDepartureMultiDate2=" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMultiPassengerType_ADT=1" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMultiPassengerType_CHD=1" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$DropDownListMultiPassengerType_INFANT=0" +
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$numberTrips=2"+
"&ControlGroupSearchView$AvailabilitySearchInputSearchView$ButtonSubmit=";

            byte[] byteArray = Encoding.UTF8.GetBytes(d);

            request.ContentLength = byteArray.Length;
            request.ContentType = "application/x-www-form-urlencoded";

            CookieContainer a = new CookieContainer();
            request.CookieContainer = a;

            request.ServicePoint.Expect100Continue = false;

            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            WebResponse response = request.GetResponse();

            dataStream = response.GetResponseStream();


            StreamReader reader = new StreamReader(dataStream);
            string text = reader.ReadToEnd();

            return text;
        }

        public static Dictionary<string, List<string>> lstDepartCity = new Dictionary<string, List<string>>();
        public Dictionary<string, List<string>> lstArriveCity = new Dictionary<string, List<string>>();

        public static void GetCity()
        {
            WebClient client = new WebClient();
            client.Encoding = Encoding.UTF8;

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
            client.DownloadStringAsync(new Uri("http://booknow.jetstar.com/Search.aspx"));
        }

        static void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(e.Result);

            HtmlNode root = doc.DocumentNode;
            HtmlNode departCities = root.SelectSingleNode("//div[@class='']");
            HtmlNodeCollection groups = departCities.SelectNodes(".//optgroup");
            foreach (HtmlNode g in groups)
            {
                string label = g.Attributes["label"].Value;
                HtmlNodeCollection cities = g.SelectNodes(".//option");
                List<string> place = new List<string>();
                foreach (HtmlNode city in cities)
                {
                    place.Add(city.InnerText);
                }
                lstDepartCity.Add(label, place);
            }
        }
    }
}
